package com.tianji.learning.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.DateUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.po.PointsRecord;
import com.tianji.learning.domain.vo.PointsStatisticsVO;
import com.tianji.learning.enums.PointsRecordType;
import com.tianji.learning.mapper.PointsRecordMapper;
import com.tianji.learning.service.IPointsRecordService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 学习积分记录，每个月底清零 服务实现类
 * </p>
 *
 * @author whx
 * @since 2025-01-11
 */
@Service
public class PointsRecordServiceImpl extends ServiceImpl<PointsRecordMapper, PointsRecord> implements IPointsRecordService {

    @Override
    public void addPointsRecord(Long userId, int points, PointsRecordType type) {
        int realPoints = points;
        int maxPoints = type.getMaxPoints();
        // judge maxPoints is 0 or not
        if(maxPoints > 0){
            // limit
            // 2.有，则需要判断是否超过上限
            LocalDateTime begin = DateUtils.getDayStartTime(LocalDateTime.now());
            LocalDateTime end = DateUtils.getDayEndTime(LocalDateTime.now());

            int havePoints = queryUserPointsTodayByType(userId, type, begin, end);

            if(havePoints >= maxPoints){
                return;
            }

            // 2.4.没超过，保存积分记录
            if(havePoints + points > maxPoints){
                realPoints = maxPoints - havePoints;
            }

        }

        PointsRecord pointsRecord = new PointsRecord();
        pointsRecord.setUserId(userId);
        pointsRecord.setPoints(realPoints);
        pointsRecord.setType(type);

        save(pointsRecord);
    }

    @Override
    public List<PointsStatisticsVO> today() {
        // 1.获取用户
        Long userId = UserContext.getUser();
        // 2.获取日期
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime begin = DateUtils.getDayStartTime(now);
        LocalDateTime end = DateUtils.getDayEndTime(now);
        // 3.构建查询条件
        QueryWrapper<PointsRecord> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(PointsRecord::getUserId, userId)
                .between(PointsRecord::getCreateTime, begin, end);
        // 4.查询
        List<PointsRecord> list = getBaseMapper().queryUserPointsByDate(wrapper);
        if (CollUtils.isEmpty(list)) {
            return CollUtils.emptyList();
        }
        // 5.封装返回
        List<PointsStatisticsVO> vos = new ArrayList<>(list.size());
        for (PointsRecord p : list) {
            PointsStatisticsVO vo = new PointsStatisticsVO();
            vo.setType(p.getType().getDesc());
            vo.setMaxPoints(p.getType().getMaxPoints());
            vo.setPoints(p.getPoints());
            vos.add(vo);
        }
        return vos;
    }

    /**
     * get currentUser`s points by type
     * @param userId
     * @param type
     * @param begin
     * @param end
     * @return
     */
    private int queryUserPointsTodayByType(Long userId, PointsRecordType type, LocalDateTime begin, LocalDateTime end) {

        List<PointsRecord> recordList = this.lambdaQuery()
                .eq(PointsRecord::getUserId, userId)
                .eq(PointsRecord::getType, type)
                .between(PointsRecord::getCreateTime, begin, end)
                .list();

        if(CollUtil.isEmpty(recordList)){
            return 0;
        }

        return recordList.stream().map(PointsRecord::getPoints).reduce(0, Integer::sum);
    }
}
